/********************************************************/
/*	Copyright (C) 2016 Gong Li Bin		 	*/
/*	Project:	GlbLib-1.0.0			*/
/*	Author:		gong_libin			*/
/*	Date:		2016_06_01			*/
/*	File:		GlbPro.h			*/
/********************************************************/

#ifndef _GLBPRO_H
#define	_GLBPRO_H

#include "GlbDef.h"
#include "GlbUtil.h"
#include <arpa/inet.h>

namespace GlbNet
{

/* head size */
#define	GLB_PRO_EXPA			4
#define	GLB_PRO_HEAD			12

#define	GLB_PRO_FLAG			0xe8

/* protocol type */
#define	GLB_PRO_GLBRL			0x00
#define	GLB_PRO_DATA			0x01

/* no or yes */
#define	GLB_PRO_N			0x00
#define	GLB_PRO_Y			0x01

/* 0 or 1 */
#define	GLB_PRO_0			0x00
#define	GLB_PRO_1			0x01

typedef struct tagGlbProHead
{
	UCHAR m_ucFlag;
	UCHAR m_ucVersion;
	UCHAR m_ucProtocol;
	UCHAR m_ucWide;
	UCHAR m_ucResponse;
	UCHAR m_ucExpand;
	UCHAR m_ucType;
	UCHAR m_ucVerb;
	UCHAR m_ucAttr;
	UCHAR m_ucResult;
	USHORT m_usTotal;
	int m_iLength;
}GLBPROHEAD_S;

class CGlbPro
{
public:
	CGlbPro();
	virtual ~CGlbPro();

	UCHAR GlbProGetFlag();
	UCHAR GlbProGetWide();
	UCHAR GlbProGetType();
	UCHAR GlbProGetVerb();
	UCHAR GlbProGetAttr();
	int GlbProGetLength();
	USHORT GlbProGetTotal();
	UCHAR GlbProGetExpand();
	UCHAR GlbProGetResult();
	UCHAR GlbProGetVersion();
	UCHAR GlbProGetProtocol();
	UCHAR GlbProGetResponse();

	UCHAR* GlbProGetBody();
	UCHAR* GlbProGetExHead();
	GLBPROHEAD_S* GlbProGetHead();

	void GlbProPutFlag(UCHAR ucFlag);
	void GlbProPutWide(UCHAR ucWide);
	void GlbProPutType(UCHAR ucType);
	void GlbProPutVerb(UCHAR ucVerb);
	void GlbProPutAttr(UCHAR ucAttr);
	void GlbProPutLength(int iLength);
	void GlbProPutTotal(USHORT usTotal);
	void GlbProPutExpand(UCHAR ucExpand);
	void GlbProPutResult(UCHAR ucResult);
	void GlbProPutVersion(UCHAR ucVersion);
	void GlbProPutProtocol(UCHAR ucProtocol);
	void GlbProPutResponse(UCHAR ucResponse);

	void GlbProPutBody(UCHAR* puszBody);
	void GlbProPutExHead(UCHAR* puszExHead);
	void GlbProPutHead(GLBPROHEAD_S* pstHead);

	void GlbProReset();
	void GlbProDisplay();
	void GlbProClone(CGlbPro& rCPro);
	void GlbProInduce(GLBPROHEAD_S* pstHead);
	void GlbProParse(UCHAR* puszPacket, int iLength);
	void GlbProCreate(UCHAR* puszPacket, int iLength);

	void GlbProRequest(UCHAR* puszPacket);
	void GlbProResponse(UCHAR* puszPacket);

private:
	UCHAR* m_puszBody;
	GLBPROHEAD_S m_stHead;
	UCHAR m_uszExHead[GLB_PRO_EXPA];

};

/* KV */
#define	GLB_PRO_KEYLEN			(sizeof(UCHAR) + sizeof(int))
typedef struct tagGlbProKv
{
	UCHAR m_ucKey;
	int m_iLength;
	UCHAR* m_puszValue;
}GLBPROKV_S;

GLBPROKV_S* GlbProKvMalloc(USHORT usTotal, int iSize);
void GlbProKvFree(GLBPROKV_S** ppstKv, USHORT usTotal);
void GlbProKvDisplay(GLBPROKV_S* pstKv, USHORT usTotal);
void GlbProKvReset(GLBPROKV_S* pstKv, USHORT usTotal, int iSize);
int GlbProKvInput(GLBPROKV_S* pstKv, USHORT usTotal, UCHAR* puszPacket, int iLength);
int GlbProKvOutput(GLBPROKV_S* pstKv, USHORT usTotal, UCHAR* puszPacket, int iLength);

/* WKV */
#define	GLB_PRO_WKEYLEN			(sizeof(USHORT) + sizeof(int))
typedef struct tagGlbProWkv
{
	USHORT m_usKey;
	int m_iLength;
	UCHAR* m_puszValue;
}GLBPROWKV_S;

GLBPROWKV_S* GlbProWkvMalloc(USHORT usTotal, int iSize);
void GlbProWkvFree(GLBPROWKV_S** ppstWkv, USHORT usTotal);
void GlbProWkvDisplay(GLBPROWKV_S* pstWkv, USHORT usTotal);
void GlbProWkvReset(GLBPROWKV_S* pstWkv, USHORT usTotal, int iSize);
int GlbProWkvInput(GLBPROWKV_S* pstWkv, USHORT usTotal, UCHAR* puszPacket, int iLength);
int GlbProWkvOutPut(GLBPROWKV_S* pstWkv, USHORT usTotal, UCHAR* puszPacket, int iLength);

/* HDRS */
typedef struct tagGlbProHdrs
{
	UCHAR m_ucFlag;
	struct {
		UCHAR m_ucExpa:1;
		UCHAR m_ucResp:1;
		UCHAR m_ucWide:1;
		UCHAR m_ucProt:1;
		UCHAR m_ucVers:4;
	} m_stOpts;
	UCHAR m_ucType;
	UCHAR m_ucVerb;
	UCHAR m_ucAttr;
	UCHAR m_ucResult;
	USHORT m_usTotal;
	int m_iLength;
}GLBPROHDRS_S;

void GlbProDisplay(GLBPROHDRS_S* pstHdrs);
void GlbProParse(GLBPROHDRS_S* pstHdrs, UCHAR* puszPacket, int iLength);
void GlbProCreate(GLBPROHDRS_S* pstHdrs, UCHAR* puszPacket, int iLength);

} /* GlbNet */

#endif /* _GLBPRO_H */
